iT邦幫忙

2026 iThome 鐵人賽

DAY 6
1
JavaScript

不只是快 —— Bun 30 天:從底層架構、全套工具鏈到生產部署系列 第 6

Bun 的 Bundler:內建打包,Vite/Rolldown 之外的另一種選擇(中篇-進階篇)

  • 分享至 

  • xImage
  •  

bun_bundler_advanced

前言

這裡我們會示範 bun 打包的精髓之一,一體化處理,在古早的年代有 Gulp
這類東西,我們一體化的操作,對於 CI/CD 或是自己搞一套腳本去 build 一整套留流程
是沒有問題的,這裡我們會展示一些深入的進階用法,上乾貨!

一體化處理 bun.build

這裏 bun 可以寫 typescript 腳本以實現利用 typescript/javascript 去 build 相關指令
這個好處是,可以整合到 js/ts 腳本裡面去做執行,對 CI/CD 也好,或是一些工作流程很有用處

舉個例子我們建構的腳本 : build.ts

const result = await Bun.build({
  entrypoints: ["./src/index.tsx"],
  outdir: "./build",
  target: "browser",
  minify: true,
  sourcemap: "external",
  splitting: true, // 開啟 code splitting
});

if (!result.success) {
  console.error("Build failed");
  for (const message of result.logs) {
    console.error(message);
  }
  process.exit(1);
}

for (const output of result.outputs) {
  console.log(output.path, output.loader, output.kind);
}

構建出來的 outputs 是 BuildArtifact 物件,它們是 Blob 加上額外屬性,所以可以直接餵給 HTTP

const { outputs } = await Bun.build({
  entrypoints: ["./src/index.tsx"],
  outdir: "./build",
});

Bun.serve({
  port: 3000,
  fetch(req) {
    const url = new URL(req.url);
    const file = outputs.find(o => o.path.endsWith(url.pathname));
    if (file) return new Response(file); // Bun 自動設定 Content-Type / ETag
    return new Response("Not found", { status: 404 });
  },
});

這樣可以建構一整個工具鏈

FileSystemRouter 產生多個 entrypoint

const router = new Bun.FileSystemRouter({
  style: "nextjs",
  dir: "./pages",
});

const entrypoints = Object.values(router.routes);

await Bun.build({
  entrypoints,
  outdir: "./build",
  target: "browser",
});

Bun plugin API

我們可以把 bun plugin 同時用在 Bundler runtime 上面,實現 build pipline
如果早期 js 的使用者有用過 Gulp 之類的,現在 bun 已經可以內建實現相關應用

plugin 的範例如下,我們這裡假設作為 yaml loader 去做處理

import { plugin } from "bun";

plugin({
  name: "yaml-loader",
  setup(build) {
    build.onLoad({ filter: /\.yaml$/ }, async (args) => {
      const text = await Bun.file(args.path).text();
      // 這裡可以用任何 yaml parser 轉成 JS object
      return {
        contents: `export default ${JSON.stringify(text)}`,
        loader: "js",
      };
    });
  },
});

--compile bun 獨有的奧義!

上面有提及,我這直接上示範

# 把 TS/JS 直接編譯成單一可執行檔,內建 Bun runtime
bun build ./cli.ts --compile --outfile demo-cli

# 執行
./demo-cli

結論

我們這裡展示如何一體化使用 bun 去處理 bundler 相關的解法,
我們下回會講到奧義篇,會講到一些進階以外的技巧


上一篇
Bun 的 Bundler:內建打包,Vite/Rolldown 之外的另一種選擇(上篇-基礎篇)
下一篇
Bun 的 Bundler:內建打包,in-memory bundling(下篇-特別篇)
系列文
不只是快 —— Bun 30 天:從底層架構、全套工具鏈到生產部署10
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言